home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / mercury / idxfile.c < prev    next >
Text File  |  1995-02-10  |  7KB  |  332 lines

  1. /*
  2.  
  3. MercuryInstaller IDXファイル読み込みルーチン
  4.  
  5. Copyright (c) Delmonta
  6.  
  7. */
  8.  
  9. #include<stdio.h>
  10. #include<stdarg.h>
  11. #include<string.h>
  12. #include<stdlib.h>
  13. #include<dos.h>
  14. #include<farstr.h>
  15. #include<ctype.h>
  16.  
  17. #include"mercury.h"
  18. /*---------------------------------定数と型----------------------------------*/
  19. typedef    enum
  20. {
  21.     DRIVE,KEYWORD,PROGRAM,MAKE,DIR,MANUAL,README,COPY,XCOPY,COMMANDNUM,
  22.     NULLLINE=COMMANDNUM,
  23. } COMMAND_T;
  24. /*-----------------------------グローバル変数--------------------------------*/
  25. static    char    *Filename=NULL;        /* 読み込み中のファイル名     */
  26. static    int    Linepos;        /* 現在の行番号               */
  27.  
  28. static    char    *Command[COMMANDNUM] =    /* .idxファイルの各パラメータ */
  29. {
  30.     "DRIVE","KEYWORD","PROGRAM","MAKE","DIR","MANUAL","README",
  31.     "COPY","XCOPY"
  32. };
  33. /*---------------------------エラーを出力して終了----------------------------*/
  34. /* メニュー画面ができあがる前の段階だから、単にメッセージを出力して終了するだ*/
  35. /* けでよい                                                                  */
  36. /*---------------------------------------------------------------------------*/
  37. static    void    die(char *s,...)
  38. {
  39.     va_list    ap;
  40.     va_start(ap,s);
  41.  
  42.     if    (Filename!=NULL)
  43.         fprintf(stderr,"%s %d:",Filename,Linepos);
  44.  
  45.     vfprintf(stderr,s,ap);
  46.     putc('\n',stderr);
  47.     exit(1);
  48. }
  49. /*---------------------------ファイルのオープン------------------------------*/
  50. static    FILE    *xfileopen(char *filename)
  51. {
  52.     FILE    *fp=fopen(filename,"r");
  53.  
  54.     if    (fp==NULL)
  55.         die("%sが見つかりません",filename);
  56.  
  57.     Filename = filename;
  58.  
  59.     printf("%sを読み込み中です ",filename);
  60.     return fp;
  61. }
  62. /*-----------------------エラー処理を含むメモリ管理--------------------------*/
  63. static    char    ERR_NOMEM[] = "メモリ不足です";
  64.  
  65. static void far    *farmalloc_die(size_t size)
  66. {
  67.     void far *p = far_sbrk(size);
  68.  
  69.     if    (p==NULL)
  70.         die(ERR_NOMEM);
  71.  
  72.     return p;
  73. }
  74.  
  75. static    void far *farcalloc_die(size_t size)
  76. {
  77.     void far *p = farmalloc_die(size);
  78.  
  79.     far_memset(p,'\0',size);
  80.  
  81.     return p;
  82. }
  83.  
  84. static    void    *nearmalloc_die(size_t size)
  85. {
  86.     void    *p = malloc(size);
  87.     if    (p==NULL)
  88.         die(ERR_NOMEM);
  89.  
  90.     return p;
  91. }
  92.  
  93. static    char    *nearstrdup_die(char *s)
  94. {
  95.     s = strdup(s);
  96.  
  97.     if    (s==NULL)
  98.         die("dead from nearstrdup");
  99.  
  100.     return s;
  101. }
  102.  
  103. static char far    *farstrdup_die(char *s)        /* sはfarポインタではない */
  104. {
  105.     size_t        a = strlen(s)+1;
  106.     char far    *p = farmalloc_die(a);
  107.  
  108.     far_memcpy(p,s,a);
  109.  
  110.     return p;
  111. }
  112. /*---------------------------Dataの未定義情報の整理--------------------------*/
  113. static    void    data_storeall(void)
  114. {
  115.     Datanum++;
  116.  
  117.     if    ((Datanum & 63)==0)
  118.         putchar('.');
  119.  
  120.     if    (Data->make==NULL)
  121.         Data->make = "";
  122.  
  123.     if    (Data->keywords==0)
  124.         die("検索キーワードが指定されていません");
  125.  
  126.     #if    0
  127.         if    (Data->dir==NULL && Data->copy==NULL)
  128.             die("データのディレクトリを指定してください");
  129.  
  130.         /* サークル紹介データのように、マニュアルだけのものも*/
  131.         /* あるかもしれないのでこの警告を出すかどうかは保留  */
  132.     #endif
  133. }
  134. /*-----------------------------KEYWORDコマンド-------------------------------*/
  135. static    void    cmd_keyword(char *p)
  136. {
  137.     if    (Datanum<0)
  138.     {
  139.         for    (p=strtok(p,Separators) ; p!=NULL ;
  140.                 p=strtok(NULL,Separators) )
  141.         {
  142.             if    (Keywordnum >= MEMBERSOF(Keyword))
  143.                 die("キーワードの数が多すぎます");
  144.  
  145.             Keyword[Keywordnum++] = nearstrdup_die(p);
  146.         }
  147.     }
  148.     else
  149.     {
  150.         int        i;
  151.         KEYWORD_T    f = 0;
  152.  
  153.         for    (p=strtok(p,Separators) ; p!=NULL ;
  154.                 p=strtok(NULL,Separators) )
  155.         {
  156.             for    (i=0 ; i<Keywordnum ; i++)
  157.             {
  158.                 if    (strcmp(Keyword[i],p)==0)
  159.                 {
  160.                     f |= 1UL<<i;
  161.                     goto nexttoken;
  162.                 }
  163.             }
  164.             die("不正なキーワードです:%s",p);
  165.         nexttoken:
  166.             ;
  167.         }
  168.         Data->keywords = f;
  169.     }
  170. }
  171. /*------------------------------PROGRAMコマンド------------------------------*/
  172. static    void    cmd_program(char *s)
  173. {
  174.     struct DATA far    *data = farcalloc_die(sizeof(struct DATA));
  175.  
  176.     if    (Datanum>=0)    /* 最初のPROGRAM指定ではない */
  177.     {
  178.         data_storeall();
  179.         data->next = Data;
  180.     }
  181.     else
  182.     {
  183.         data->next = NULL;
  184.         Datanum = 0;
  185.     }
  186.  
  187.     Data = data;
  188.     Data->title = farstrdup_die(strchop(s,TITLEWIDTH));
  189. }
  190. /*----------------------------COPY/XCOPYコマンド-----------------------------*/
  191. static    void    cmd_copy(char *s,bool isxcopy)
  192. {
  193.     struct    COPYDATA_T far    *p = farmalloc_die(sizeof(struct COPYDATA_T));
  194.  
  195.     p->string = farstrdup_die(s);
  196.     p->isxcopy = isxcopy;
  197.  
  198.     p->next = Data->copy;
  199.     Data->copy = p;
  200. }
  201. /*----------------------------トークンの切り出し-----------------------------*/
  202. static    COMMAND_T    getcommand(char *buf,char **next)
  203. {
  204.     int    i;
  205.     char    *p,*q;
  206.  
  207.     while    (isspace(*buf))
  208.         buf++;
  209.  
  210.     if    (*buf=='\0')
  211.         return NULLLINE;
  212.  
  213.     if    ((p=strchr(buf,':'))==NULL)
  214.         die("コマンドが不正です:%s",buf);
  215.  
  216.     q = p+1;
  217.     while    (isspace(*q))
  218.         q++;
  219.  
  220.     *next = q;
  221.  
  222.     do
  223.         p--;
  224.     while (isspace(*p));
  225.  
  226.     *++p = '\0';
  227.  
  228.     p = strchr(q,'\n');
  229.     if    (p)
  230.         *p = '\0';
  231.  
  232.     for    (i=0 ; i<MEMBERSOF(Command) ; i++)
  233.     {
  234.         if    (strcmp(buf,Command[i])==0)
  235.             goto end;
  236.     }
  237.  
  238.     if    (Flag_noignore)
  239.         die("不正なコマンドです:%s\n",buf);
  240.     else
  241.         return NULLLINE;
  242. end:
  243.     return (COMMAND_T)i;
  244. }
  245. /*-----------------------------メインルーチン--------------------------------*/
  246. extern    void    readidxfile(char *filename)
  247. {
  248.     FILE        *fp = xfileopen(filename);
  249.     COMMAND_T    code;
  250.     int        flag = 0; /* コマンドの二重指定を防ぐためのフラグ */
  251.     char        buf[512];
  252.     char        *s;
  253.  
  254.     Datanum = -1;
  255.     Linepos = 0;
  256.  
  257.     if    (Drive=='\0')
  258.     {
  259.         if    (filename[1]==':')
  260.             Drive = filename[0];
  261.         else
  262.             Drive = bdos(0x19,0,0) + 'A';    /* カレントドライブ */
  263.     }
  264.  
  265.     while    (fgets(buf,sizeof(buf),fp)!=NULL)
  266.     {
  267.         Linepos++;
  268.  
  269.         code = getcommand(buf,&s);
  270.         if    (code==NULLLINE)
  271.             continue;
  272.  
  273.         if    (Datanum<0 && code>PROGRAM)
  274.             die("PROGRAMコマンドの前に%sコマンドがあります\n",
  275.                             Command[code]);
  276.  
  277.         if    (flag & (1<<code))
  278.             die("%sコマンドが2回指定されています",Command[code]);
  279.  
  280.         switch    (code)
  281.         {
  282.         case KEYWORD:
  283.             cmd_keyword(s);
  284.             break;
  285.  
  286.         case PROGRAM:
  287.             cmd_program(s);
  288.             flag = 0;
  289.             break;
  290.  
  291.         case MAKE:
  292.             flag |= 1<<MAKE;
  293.             Data->make = farstrdup_die(strchop(s,MAKEWIDTH));
  294.             break;
  295.  
  296.         case DIR:
  297.             flag |= 1<<DIR;
  298.             Data->dir = farstrdup_die(s);
  299.             break;
  300.  
  301.         case COPY:
  302.         case XCOPY:
  303.             cmd_copy(s,code);
  304.             break;
  305.  
  306.         case README:
  307.             flag |= 1<<README;
  308.             Data->readme = farstrdup_die(s);
  309.             break;
  310.  
  311.         case MANUAL:
  312.             flag |= 1<<MANUAL;
  313.             Data->manual = farstrdup_die(s);
  314.             break;
  315.  
  316.         case DRIVE:
  317.             if    (isalpha(*s))
  318.                 Drive=*s;
  319.             else
  320.                 die("不正なドライブ名です:%s\n",s);
  321.             break;
  322.         }
  323.     }
  324.  
  325.     fclose(fp);
  326.     data_storeall();
  327.  
  328.     putchar('.');
  329.     putchar('\n');
  330. }
  331. /*----------------------------End of idxfile.c-------------------------------*/
  332.